#include "SpeciesPropertiesUI.h"
#include "../../dataengine/VibModelFileManager.h"
#include "../../glutil/FBO.h"
#include "../../glutil/ModelRenderer.h"
#include <QGLPixelBuffer>
#include <QFileDialog>
#include <QtGlobal>
#include <QDebug>
SpeciesPropertiesWidget::SpeciesPropertiesWidget(QWidget* parent) : QWidget( parent )
{
	ui.setupUi(this);
	for(int i=1;i<20;++i)
		ui.speciesIDBox->addItem(QString("").setNum(i));

	m_currentModel = 1;
	m_currentSpecies = 0;
	ui.preview->setText("No file selected");
    connect(ui.speciesIDBox,SIGNAL(currentIndexChanged(int)), this, SLOT(selectedSpeciesChanged(int)));
	connect(ui.browseButton,SIGNAL(clicked()), this, SLOT(browseFile()));
	connect(ui.modelsBox,SIGNAL(currentIndexChanged(int)),this,SLOT(uiChangeHappened()));
	connect(ui.baseScaleSpinbox,SIGNAL(valueChanged(double)),this,SLOT(dataChangeHappened()));
	m_currentFile = "";
}


SpeciesPropertiesWidget::~SpeciesPropertiesWidget()
{
	
}

void SpeciesPropertiesWidget::dataChangeHappened()
{
	sendSpeciesChangedSignal();
}

void SpeciesPropertiesWidget::sendSpeciesChangedSignal()
{
	slotsdata::SpeciesProperties props;
	std::map<QString, geom::PolyObject>::iterator modelsIt;
	std::map<QString, geom::PolyObject>::iterator modelsEnd = m_speciesObjects.end();
	for(modelsIt = m_speciesObjects.begin(); modelsIt != modelsEnd; ++modelsIt)
		props.addFile(modelsIt->first, modelsIt->second);

	props.setBaseScale(ui.baseScaleSpinbox->value());

	std::map<int,QString>::iterator it;
	std::map<int,QString>::iterator end = m_modelFiles.end();

	for(it = m_modelFiles.begin(); it!=end;++it)
		props.setSpeciesFile(it->first, it->second);

	emit speciesChanged(props);
}

void SpeciesPropertiesWidget::browseFile()
{
	QFileDialog::Options options;
	QString selectedFilter;
	QString fileName = QFileDialog::getOpenFileName(this,
			tr("Select Object File"),
			QString("."),
			tr("ViBos Object Files(*.vib);;All Files"),
			&selectedFilter,
			options);
	if (fileName.isEmpty())
		return ;

	int speciesID = ui.speciesIDBox->currentText().toInt();
	m_modelFiles[speciesID] = fileName;
	ui.fileNameEdit->setText(fileName);

	uiChangeHappened();
	sendSpeciesChangedSignal();
}

void SpeciesPropertiesWidget::selectedSpeciesChanged(int currentIndex)
{
	std::map<int,QString>::iterator it = m_modelFiles.find(currentIndex);

	m_currentSpecies = currentIndex;
	if(it == m_modelFiles.end())
	{
		ui.preview->setText("No file selected");
		ui.fileNameEdit->setText("");
		return;
	}

	ui.fileNameEdit->setText(it->second);
	uiChangeHappened();
}

void SpeciesPropertiesWidget::uiChangeHappened()
{
	ui.modelsBox->blockSignals(true);
	QString filename = ui.fileNameEdit->text();
	if(filename!= m_currentFile || ui.modelsBox->currentIndex()!=m_currentModel)
	{
		m_currentModel = ui.modelsBox->currentIndex();
		std::map<QString, geom::PolyObject>::iterator it = m_speciesObjects.find(filename);
		if(it == m_speciesObjects.end()) // Si el archivo no esta cargado, lo hacemos
		{
			// We take the file selected for the selected species
			dataengine::VibModelFileManager fileLoader(filename.toStdString());
			// If none, return
			if(!fileLoader.canLoadFile())
			{
				ui.preview->setText("File could not be loaded");
				return;
			}
			// Load it
			auto_ptr < geom::PolyObject> obj = fileLoader.loadFile();
			m_speciesObjects.insert(std::pair<QString,geom::PolyObject>(ui.fileNameEdit->text(), *obj));
			it = m_speciesObjects.find(filename);
		}
		// Ahora que ya tenemos el archivo cargado, miramos qué modelos tiene, y los añadimos al combobox
		int numModels = (*it).second.getNumberOfModels();
		while(ui.modelsBox->count() > 0)
			ui.modelsBox->removeItem(0);

		for(int i=0;i<numModels;++i)
		{
			std::string name = (*it).second.getModel(i).name();
			ui.modelsBox->addItem(QString("").setNum(i) + QString(" - ")+ QString(name.c_str()));
		}
		if(m_currentModel > ui.modelsBox->count())
			m_currentModel = ui.modelsBox->count();
		ui.modelsBox->setCurrentIndex(m_currentModel);
		m_currentFile = filename;
	}

	updateSelectedView(filename, m_currentModel);
	ui.modelsBox->blockSignals(false);
}

void SpeciesPropertiesWidget::updateSelectedView(QString filename, int modelNum)
{
	std::map<QString, geom::PolyObject>::iterator it = m_speciesObjects.find(filename);
	if(it == m_speciesObjects.end())
	{
		qDebug()<<"m_speciesObjects has no elements";
		return;
	}

	if(modelNum >= it->second.getNumberOfModels())
	{
		qDebug()<<"not enough models in file";
		return;
	}

	if(modelNum < 0)
	{
		qDebug()<<"Erroneous modelnum :"<<modelNum;
		return;
	}

	const geom::PolyModel * model = &(it->second.getModel(modelNum));
	if(model == NULL)
	{
		qDebug()<<"NULL model\n";
		return ;
	}

	geom::BBox bbox = model->getModelBoundingBox();
	QGLPixelBuffer pbuffer(128,128);
	pbuffer.makeCurrent();
	// Generate an image of it to a pixel buffer
	{
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		float hside = bbox.m_side/2;
		geom::Point3D p = bbox.m_center;
		glOrtho(p.x-hside,p.x+hside,p.y-hside,p.y+hside,0.1,hside*5);
		glViewport(0,0,128,128);
		glMatrixMode(GL_MODELVIEW);

		glLoadIdentity();
		glClearColor(0.8,0.7,0.9,1.0);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glutil::ModelRenderer renderer(*model);
		glutil::GLInstanceInfo info;
		for(int i=0;i<3;++i)
			info.m_location[i] = 0.0, info.m_rotation[i] = 0.0;
		info.m_scale = 1.0;
		renderer.addInstance(info);
		glTranslatef(0,0,-2*hside);
		renderer.renderAll(true);
	}
	QImage image = pbuffer.toImage();
	ui.preview->setPixmap(QPixmap::fromImage(image));
}


